home *** CD-ROM | disk | FTP | other *** search
- /*
- * TmDrag.c --
- * This module contains the main set of functions
- * for drag and drop
- *
- * Copyright 1993 Jan Newmarch, University of Canberra.
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The author
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
-
- #include "tm.h"
- #include "tmFuncs.h"
- #include <Xm/Xm.h>
-
- #ifndef MOTIF11
- #include <Xm/DragDrop.h>
- #include <Xm/AtomMgr.h>
-
- /* I shouldn't have to do this, but I do... */
- #ifdef DD_NAMES_CHANGED
- extern XtResource DSResources[];
- extern Cardinal NumDSResources;
- #else
- extern XtResource _XmDSResources[];
- extern Cardinal _XmNumDSResources;
- #endif
-
- Boolean Tm_SettingDropResources = False;
- Boolean Tm_SettingDropProc = False;
-
- Tm_Widget *Tm_HackWidgetPtr; /* see gripe in next function */
- Tm_Widget *Tm_HackDragWidgetPtr;
-
-
- /*--------------------------------------------------------------
- *
- * Tm_DragContextCmd --
- *
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * See the user documentation.
- *
- *--------------------------------------------------------------
- */
-
- int
- Tm_DragContextCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Information about button widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- char **argv; /* Argument strings. */
- {
- Tm_Widget *butPtr = (Tm_Widget *) clientData;
- char c;
- Arg args[TM_MAXARGS];
- int num_args;
-
- if (argc < 2) {
- sprintf(interp->result,
- "wrong # args: should be \"%.50s option [arg arg ...]\"",
- argv[0]);
- return TCL_ERROR;
- }
- c = argv[1][0];
-
- if ((c == 'd') && (strcmp(argv[1], "dropTransferStart") == 0)) {
- Widget dropTransfer;
- WidgetClass class = xmDropTransferObjectClass;
-
- XtInitializeWidgetClass(class);
- /* now we hit a big hole. From here, control goes to Tm_DropTransferHandler.
- * we get there with the DropTransfer widget as 1st arg. Alas, woe, etc,
- * there is no userData field on this animal for us to pass in a new wPtr
- * for it. That means we've lost access to the Tcl interpreter :-(((.
- * Solutions: (a) build a hash table from Xt widget to Tm widget. Cleanest,
- * generalises to Xt, etc. (b) wave a magic wand so that there *is* a
- * userData field. (c) Set a global with butPtr in it. Guess which hack
- * we choose...
- */
- Tm_HackWidgetPtr = butPtr;
-
- /* hmmm, looks like we need to set some resources *right now*.
- Pity the doco doesn't tell me this...
- */
- Tm_SetValues(butPtr->pathName, interp, butPtr->widget, butPtr->widget,
- class, argv+2, argc-2, args, &num_args);
- dropTransfer = XmDropTransferStart(butPtr->widget, args, num_args);
-
- /*
- Tm_SetValues(butPtr->pathName, interp, dropTransfer, dropTransfer,
- class, argv+2, argc-2, args, &num_args);
- XtSetValues(dropTransfer, args, num_args);
- */
- }
- return TCL_OK;
- }
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_DropTransferHandler --
- *
- * handler for when a drop starts moving data
- *
- * Results:
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
- /* ARGSUSED */
- void
- Tm_DropTransferHandler(w, closure, seltype, type, value, length, format)
- Widget w;
- XtPointer closure;
- Atom *seltype;
- Atom *type;
- XtPointer value;
- unsigned long *length;
- int *format;
- {
- Tcl_Interp *interp;
- Widget droppedOnWidget = (Widget) closure;
- Tm_Widget *wPtr = Tm_HackWidgetPtr; /* this is the drag context widget */
- Tm_TransferStruct call_data;
- Atom COMPOUND_TEXT;
- Atom TEXT;
- Atom STRING;
- char *command;
- char *new_command;
- char *msg;
-
-
- COMPOUND_TEXT = XmInternAtom(XtDisplayOfObject(w),
- "COMPOUND_TEXT", False);
- TEXT = XmInternAtom(XtDisplayOfObject(w),
- "TEXT", False);
- STRING = XmInternAtom(XtDisplayOfObject(w),
- "STRING", False);
-
- command = wPtr->transferProc;
- interp = wPtr->interp;
-
- msg = NULL;
- if (*type == COMPOUND_TEXT) {
- /* I know nothing about Compound Strings, so I'll cheat
- by letting Motif do the work
- */
- XmString xmstr;
-
- xmstr = XmCvtCTToXmString(value);
- XmStringGetLtoR(xmstr, XmFONTLIST_DEFAULT_TAG, &msg);
- XmStringFree(xmstr);
- } else
- if (*type == TEXT || *type == STRING) {
- /* are these null terminated? just in case... */
- msg = XtMalloc(*length + 1);
- strncpy(msg, value, *length);
- msg[*length] = '\0';
- }
- call_data.value = msg;
- call_data.closure = (char *) closure;
-
- new_command = Tm_ExpandPercents(wPtr->pathName, w, NULL,
- &call_data, command);
-
- if (Tcl_GlobalEval(interp, new_command) != TCL_OK) {
- msg = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
- if (msg == NULL) {
- msg = interp->result;
- }
- XtAppWarningMsg(XtWidgetToApplicationContext(w),
- "TclError", "TclError", "TclError", msg, NULL, 0);
- }
-
- XtFree(new_command);
- }
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_DropProcHandler --
- *
- * handler for when a drop starts on a widget
- *
- * Results:
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
- void
- Tm_DropProcHandler(w, client_data, call_data)
- Widget w;
- XtPointer client_data;
- XtPointer call_data;
- {
- XmDropProcCallback dropData;
- Tm_Widget *wPtr;
- Tm_Widget *dcPtr;
- Tcl_Interp *interp;
- char *dropProc;
- Widget dragContext;
- char *command;
-
-
- XtVaGetValues(w, XmNuserData, &wPtr, NULL);
- dropProc = wPtr->dropProc;
- interp = wPtr->interp;
-
- dropData = (XmDropProcCallback) call_data;
- dragContext = dropData->dragContext;
-
- /* this thing has no Tm name yet */
- dcPtr = (Tm_Widget *) XtMalloc(sizeof(Tm_Widget));
- dcPtr -> interp = wPtr -> interp;
- dcPtr -> widget = dragContext;
- dcPtr -> pathName = XtMalloc(strlen(wPtr->pathName) + 3);
- strcpy(dcPtr -> pathName, wPtr -> pathName);
- strcat(dcPtr -> pathName, "..");
- dcPtr -> parent = NULL;
- dcPtr -> dropProc = NULL;
-
- Tm_StoreWidgetInfo(dcPtr->pathName, dcPtr, dcPtr->interp);
-
- Tcl_CreateCommand (dcPtr->interp, dcPtr->pathName, Tm_DragContextCmd,
- (ClientData) dcPtr, (void (*) ()) NULL);
-
- /* this damn thing has no class pointer!!! */
- command = Tm_ExpandPercents(dcPtr->pathName, dcPtr->widget, dropData->event,
- call_data, dropProc);
-
- if (Tcl_GlobalEval(interp, command) != TCL_OK) {
- char *msg;
-
- msg = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
- if (msg == NULL) {
- msg = interp->result;
- }
- XtAppWarningMsg(XtWidgetToApplicationContext(w),
- "TclError", "TclError", "TclError", msg, NULL, 0);
- }
-
- XtFree(command);
- }
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_DropSiteSetValues --
- *
- * set resource values on a widget
- *
- * Results:
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
- void
- Tm_DropSiteSetValues(pathName, interp, w, argv, argc, args, num_args)
- char *pathName;
- Tcl_Interp *interp;
- Widget w;
- char **argv;
- int argc;
- Arg args[];
- int *num_args;
- {
- #ifdef DD_NAMES_CHANGED
- int num_resources = NumDSResources;
- #else
- int num_resources = _XmNumDSResources;
- #endif
- int num_values = 0;
- XrmValue from, converted;
- XtArgVal new_value;
- char *resource;
- char *value;
- Tm_ClientData *client_data;
-
- if (argc > TM_MAXARGS*2) {
- return;
- }
-
- /* hack - how else do I tell between Drop set and FileSelBox set? */
- Tm_SettingDropResources = True;
-
- while (argc >= 2) {
- if (argv[0][0] != '-') {
- /* skip this one silently */
- argc -= 2; argv += 2;
- continue;
- }
- resource = argv[0]+1;
- value = argv[1];
-
- if (strcmp(resource, "dropProc") == 0) {
- /* hack - how else do I tell between drop and drag Proc? */
- Tm_SettingDropProc = True;
- }
-
- #ifdef DD_NAMES_CHANGED
- if (Tm_ConvertValueFromStringQuark(w, DSResources, num_resources,
- #else
- if (Tm_ConvertValueFromStringQuark(w, _XmDSResources, num_resources,
- #endif
- resource, value, &new_value)) {
- XtSetArg(args[num_values], resource, new_value);
- num_values++;
- } else {
- fprintf(stderr, "Conversion from String to %s failed\n",
- resource);
- }
-
- Tm_SettingDropProc = False;
-
- argc -= 2;
- argv += 2;
- }
-
- Tm_SettingDropResources = False;
-
- *num_args = num_values;
-
- /* memory leak: should XtFree all new_values stored in args[] */
- }
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_DropSiteGetValues --
- *
- * unused
- * get the resource values out of a widget
- *
- * Results:
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
- void
- Tm_DropSiteGetValues(pathName, interp, w, class, argv, argc)
- char *pathName;
- Tcl_Interp *interp;
- Widget w;
- WidgetClass class;
- char **argv;
- int argc;
- {
- XtResourceList resources;
- int num_resources;
- int num_values = 0;
- XrmValue from, converted;
- char *new_value;
- # define MAXARGS 100
- char *resource;
- Tm_ClientData *client_data;
- Widget parent;
-
- if (argc > MAXARGS*2) {
- return;
- }
-
- parent = XtParent(w);
- XtGetResourceList(class, &resources, &num_resources);
-
- while (argc >= 2) {
- if (argv[0][0] != '-') {
- fprintf(stderr, "Skipping argument %s\n", argv[0]);
- argc -= 2; argv += 2;
- continue;
- }
- resource = argv[0]+1;
-
- if (Tm_ConvertValueToString(w, resources, num_resources,
- resource, &new_value)) {
- /* store new_value in variable in argv[1] now */
- # ifdef DEBUG
- fprintf(stderr, "Got value: %s\n", (char *) new_value);
- # endif
- /*
- Tcl_SetVar(interp, argv[1], (char *) new_value, TCL_GLOBAL_ONLY);
- */
- Tcl_SetVar(interp, argv[1], (char *) new_value, 0);
- } else {
- fprintf(stderr, "Conversion from %s to String failed\n",
- resource);
- }
- argc -= 2;
- argv += 2;
- }
- }
-
- Boolean Tm_ConvertProcHandler(w, selection, target, type, value, length, format)
- Widget w;
- Atom *selection;
- Atom *target;
- Atom *type;
- XtPointer *value;
- unsigned long *length;
- int *format;
- {
- extern Tm_Widget *Tm_HackDragWidgetPtr;
- Tm_Widget *wPtr = Tm_HackDragWidgetPtr;
- char *convertProc = wPtr->convertProc;
- Tcl_Interp *interp = wPtr->interp;
- char *command;
- char *msg, *msg_type, *msg_value;
- XmString xmstr;
-
-
- Tcl_SetVar(interp, TM_CONVERT_TYPE, "", TCL_GLOBAL_ONLY);
- Tcl_SetVar(interp, TM_CONVERT_VALUE, "", TCL_GLOBAL_ONLY);
-
- command = Tm_ExpandPercents(wPtr->pathName,
- w,
- NULL, NULL,
- convertProc);
- if (Tcl_GlobalEval(interp, command) != TCL_OK) {
- msg = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
- if (msg == NULL) {
- msg = interp->result;
- }
- XtAppWarningMsg(XtWidgetToApplicationContext(w),
- "TclError", "TclError", "TclError", msg, NULL, 0);
- XtFree(command);
- return False;
- }
- XtFree(command);
-
- /* now set results back into convertProc args */
- msg_type = Tcl_GetVar(interp, TM_CONVERT_TYPE, TCL_GLOBAL_ONLY);
- msg_value = Tcl_GetVar(interp, TM_CONVERT_VALUE, TCL_GLOBAL_ONLY);
-
- if (strcmp(msg_type, "COMPOUND_TEXT") == 0) {
- char *passtext, *ctext;
-
- xmstr = XmStringCreateLocalized(msg_value);
- ctext = XmCvtXmStringToCT(xmstr);
- passtext = XtMalloc(strlen(ctext) + 1);
- memcpy(passtext, ctext, strlen(ctext) + 1);
-
- *type = XmInternAtom(XtDisplay(w), "COMPOUND_TEXT", False);
- *value = (XtPointer) passtext;
- *length = strlen(passtext);
- *format = 8;
- XmStringFree(xmstr);
-
- return True;
- }
- return False;
- }
-
- #endif /* not MOTIF11 */
-